package com.game.modular.game.battle.info.roundInfo;


import com.baomidou.mybatisplus.extension.service.IService;
import com.game.modular.game.battle.info.roundInfo.domain.PvpBattleRoundInfo;

import com.game.modular.game.battle.info.roundInfo.dto.messageDto.PvpMessageData.PreMessageData;
import com.game.modular.game.battle.info.roundInfo.dto.messageDto.PvpMessageData.TakeActionMessage;
import lombok.extern.slf4j.Slf4j;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.game.modular.game.playerMatch.mapper.PvpBattleRoundInfoMapper;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.Objects;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

/**
 * pvp战斗回合信息(PvpBattleRoundInfo)表服务实现类
 *
 * @author cxy
 * @since 2024-09-05 17:32:31
 */
@Slf4j
@Service
public class PvpBattleRoundInfoServiceImpl extends ServiceImpl<PvpBattleRoundInfoMapper, PvpBattleRoundInfo> implements IService<PvpBattleRoundInfo> {
    @Resource
    private ValueOperations<Object, PvpBattleRoundInfo> valueOperations;;
    private static final String RedisKey = "battle:%d:PvpBattleRoundInfo";

    public void initPvpBattleRoundInfo(Long battleId) {
        PvpBattleRoundInfo build = PvpBattleRoundInfo.builder()
                .battleId(battleId)
                .battleRoundInfo(new ArrayList<>())
                .prepareRoundInfo(new PreMessageData())
                .battleRoundInfo(new ArrayList<>())
                .build();
        insert(build);
    }

    public void initBattleRoundInfo(
            Long battleId,
            Integer round,
            Integer orderOfAction
    ) {
        TakeActionMessage build = TakeActionMessage.builder()
                .battleId(battleId)
                .round(round)
                .orderOfAction(orderOfAction)
                .build();
        PvpBattleRoundInfo byId = getById(battleId);
        List<TakeActionMessage> battleRoundInfo = byId.getBattleRoundInfo();
        if (!battleRoundInfo.isEmpty()){
            battleRoundInfo.removeIf(item -> Objects.equals(item.getRound(), round) && Objects.equals(item.getOrderOfAction(), orderOfAction));
        }
        battleRoundInfo.add(build);
        byId.setBattleRoundInfo(battleRoundInfo);
        updateById(byId);
    }


    public void insert(PvpBattleRoundInfo pvpBattleRoundInfo) {
        super.save(pvpBattleRoundInfo);
        if (pvpBattleRoundInfo.getBattleId() == null) {
            throw new RuntimeException("battleId不能为空");
        }
        saveCache(pvpBattleRoundInfo);
    }

    public void saveCache(PvpBattleRoundInfo pvpBattleStatisticsInfo) {
        String key = String.format(RedisKey, pvpBattleStatisticsInfo.getBattleId());
        valueOperations.set(key, pvpBattleStatisticsInfo, 12, TimeUnit.HOURS);
    }

    public PvpBattleRoundInfo selectCache(Long id) {
        String key = String.format(RedisKey, id);
        return valueOperations.get(key);
    }

    public boolean updateById(PvpBattleRoundInfo pvpBattleRoundInfo) {
        boolean b = super.updateById(pvpBattleRoundInfo);
        saveCache(pvpBattleRoundInfo);
        return b;
    }

    public PvpBattleRoundInfo getById(Long id) {
        PvpBattleRoundInfo pvpBattleRoundInfo = selectCache(id);
        if (pvpBattleRoundInfo == null) {
            pvpBattleRoundInfo = super.getById(id);
            saveCache(pvpBattleRoundInfo);
        }
        return pvpBattleRoundInfo;
    }

    public TakeActionMessage obtainAppointTakeInfo(Long battleId, int roundCount, int orderOfAction) {
        PvpBattleRoundInfo pvpBattleRoundInfo = getById(battleId);
        List<TakeActionMessage> battleRoundInfo = pvpBattleRoundInfo.getBattleRoundInfo();
        if (battleRoundInfo != null) {
            battleRoundInfo = battleRoundInfo.stream()
                    .filter(item -> item.getRound() == roundCount && item.getOrderOfAction() == orderOfAction)
                    .collect(Collectors.toList());
        }
        return battleRoundInfo.get(0);
    }

    public void updateAppointTakeInfo(TakeActionMessage takeActionMessage) {
        PvpBattleRoundInfo pvpBattleRoundInfo = getById(takeActionMessage.getBattleId());
        List<TakeActionMessage> battleRoundInfo = pvpBattleRoundInfo.getBattleRoundInfo();
        battleRoundInfo.removeIf(item ->
                Objects.equals(item.getRound(), takeActionMessage.getRound()) &&
                        Objects.equals(item.getOrderOfAction(), takeActionMessage.getOrderOfAction())
        );
        battleRoundInfo.add(takeActionMessage);
        updateById(pvpBattleRoundInfo);
    }


    public void collectionBattleReplay(Long battleId) {
        PvpBattleRoundInfo update = new PvpBattleRoundInfo();
        update.setBattleId(battleId);
        update.setIsCollect(1);
        updateById(update);
    }
}
